#include "GVisitor.h"
#include "GSceneManager.h"
#include "GError.h"

namespace GEngine
{
	GSceneManager::GSceneManager()
	{
	}

	GSceneManager::~GSceneManager()
	{
	}

	GUInt32 GSceneManager::GetObjectCount() const
	{
		return GameObjects.size();
	}

	void GSceneManager::Append(GGameObject* Object)
	{
		GameObjects.push_back(Object);
	}

	void GSceneManager::Remove(GGameObject* Object)
	{
		GSize I = 0;
		GSize ObjectCount = GameObjects.size();
		for ( ; (I < ObjectCount) && (GameObjects[I] != Object); ++I)
		{
		}

		if (I == ObjectCount)
		{
			// No such object
			return;
		}

		GGameObject* ToRemove = GameObjects[I];
		GameObjects[I] = GameObjects.back();
		
		GameObjects.pop_back();
	}

	bool GSceneManager::Contains(GGameObject* Object) const
	{
		GSize I = 0;
		GSize ObjectCount = GameObjects.size();
		for ( ; (I < ObjectCount) && (GameObjects[I] != Object); ++I)
		{
		}

		return I < ObjectCount;
	}

	GGameObject* GSceneManager::Find(const char* Name)
	{
		//! brute force name search
		return NULL;
	}

	void GSceneManager::RemoveAll()
	{
		GameObjects.clear();
	}

	// Traverses by visiting top level nodes so user can noly use G_VO_NODE_TO_LEAF or G_VO_LEAF_TO_NODE orders
	void GSceneManager::TraverseScene(GVisitor* Visitor)
	{
		GVisitOrder Order = Visitor->GetOrder();
		GUtil::GError::DebugCheck(Order != G_VO_NODE_TO_LEAF || Order != G_VO_LEAF_TO_NODE, 
									"Wrong visit order.");

		GSize Count = GameObjects.size();
		for (GSize I = 0; I < Count; ++I)
		{
			Visitor->Traverse(GameObjects[I]);
		}
	}

	bool GSceneManager::Initialize() OVERRIDE
	{
		if (!GInitializable::Initialize())
		{
			return false;
		}

		GameObjects.reserve(100);

		return true;
	}

	void GSceneManager::Uninitialize() OVERRIDE
	{
		RemoveAll();

		GInitializable::Uninitialize();
	}

}; // namespace GScene